/*
版权@hehung所有，转载请申明
email：1398660197@qq.com
*/
#include "app_weather.h"
#include "app_main.h"
#include <yoc/init.h>
#include <drv/pin.h>
#include <yoc/at_port.h>
#include <devices/w800.h>
#include <devices/drv_snd_alkaid.h>
#include "app_main.h"
#include "board.h"
#include <cJSON.h>
#include "app_rtc.h"
#include <stdio.h>
#include <string.h>
#include "app_kv.h"

#define TAG "app_weather"

#define DEBUG_PRINT                       (STD_ON)

static aos_task_t weather_task_h;    /* Clock Alarm task handle */
static uint32_t weather_task_cycle_ms = 1000;  
static uint8_t weather_get_succ_flg = 0;
static s_WeatherType weather_info;
static uint32_t city_key = 101270101;    /* 默认成都, 因本人在成都 ^_^ */
static uint32_t weather_update_cnt = 0;  
static uint8_t weather_upt_flg = 0;    /* 天气更新标志 */

static void Weather_TaskEntry(void *arg);
static int Weather_GetWeather(void);
static void Network_W800ConnectTcpServer(char *server_ip, uint16_t port);
static void Weather_CjsonParse(char *json_data);
static void Weather_UpdateByTime(void);


/* 天气函数初始化 */
void Weather_TaskInit(void)
{
	int task_s;

	/* 从KV存储区读取音量值并设置 */
    /* 如果音量值没有被设置过，使用默认值 */
    if (1 == Kv_GetSaveStatus(KV_CITY))
    {
        city_key = Kv_ReadData(KV_CITY);
    }
	 
    task_s = aos_task_new_ext(&weather_task_h,
                            "weather_task", 
                            Weather_TaskEntry, 
                            NULL, 
                            2048*2, 
                            4);
    if (0 == task_s)
    {
        printf("APP_WEATHER Task create success\r\n");
    }
    else
    {
        printf("APP_WEATHER Task create failed\r\n");
    }
}

/* 天气函数任务入口 */
static void Weather_TaskEntry(void *arg)
{
    static uint8_t network_conn_flg = 0;
	static uint8_t cb_flg = 0;

    while (1) 
	{
		/* 回调函数只注册一次 */
		if((1 == weather_upt_flg) ||
			((0 == Rtc_GetNtpEnStatus()) && (0 == cb_flg)))
		{
			printf("\n=======================\n");
			weather_upt_flg = 0;
			weather_get_succ_flg = 0;
			/* 注册回调函数 */
        	w800_packet_input_cb_register(&Network_W800RcvCb);
			network_conn_flg = 1;
			cb_flg = 1;
			weather_update_cnt = 0;
		}
        
		if (0 == weather_get_succ_flg)
		{
			if(1 == network_conn_flg)    /* 判断NTP是否已经更新了，避免同时暂用wifi造成混乱 */
			{
				Weather_GetWeather();
			}
		}
		else
		{
			Weather_UpdateByTime();
		}
		
		aos_msleep(weather_task_cycle_ms);
    }
}

/* 定时更新天气，每一小时更新一次 */
static void Weather_UpdateByTime(void)
{
	if (weather_update_cnt > ((60*60*1000)/weather_task_cycle_ms))
	{
		weather_update_cnt = 0;
		weather_get_succ_flg = 0;
	}
	else
	{
		weather_update_cnt++;
	}
}

static int Weather_GetWeather(void) 
{
	uint16_t url_len;
	int timeout = 200;
    char url[150];
//    const uint8_t url[] = "GET http://www.weather.com.cn/data/cityinfo/101270101.html\r\n";    /* 可用，但是获取的信息不全 */

//	url_len = (uint16_t)(sizeof(url)/sizeof(uint8_t));
    sprintf(url, "GET http://api.k780.com/?app=weather.today&cityId=%d&appkey=65721&sign=5eb3b0a628853b62fb871f43ad0f7293&format=json\r\n", city_key);/* NowApi，免费200次/h，三个月 */
    url_len = strlen(url);

	/* 连接到服务器 - 天气：wthrcdn.etouch.cn */
	// Network_W800ConnectTcpServer("118.123.207.178", 80);
	Network_W800ConnectTcpServer("103.205.5.249", 80);
	w800_send_data((const uint8_t*)url, url_len, timeout);

    return 0;
}

/* 连接到指定服务器 */
static void Network_W800ConnectTcpServer(char *server_ip, uint16_t port)
{
	char ssid[32];
	int bssid[6];
	int channel;
	int rssi;
	
	w800_ap_info(ssid, bssid , &channel,  &rssi);
#if (DEBUG_PRINT == STD_ON)
	printf("ssid: %s\r\n", ssid);
	printf("channel: %d\r\n", channel);
	printf("rssi: %d\r\n", rssi);
#endif
	
	//w800_connect_remote(0, NET_TYPE_TCP_CLIENT, server_ip, port);
	w800_connect_remote(0, 2, server_ip, port);
}

/* W800数据接收回调函数 */
void Network_W800RcvCb(int linkid, 
                       void *data, 
                       size_t len, 
                       char remote_ip[16], 
                       uint16_t remote_ports)
{
	uint8_t *buf;
	buf = (uint8_t *)data;
	cJSON *body = NULL;  
	cJSON *cjson_succ_flg = NULL; 

	if((0 == len) || (NULL == buf))
	{
		return;
	}

#if (DEBUG_PRINT == STD_ON)
	printf("receive data len: %d\r\n",len);
	printf("receive data:");
	for(uint16_t i = 0; i < len; i++)
	{
		printf("%c", buf[i]);	
	}	
	printf("\r\n");
#endif

	body = cJSON_Parse((const char*)buf);
	cjson_succ_flg = cJSON_GetObjectItem(body, "success");    /* 获取天气是否成功标志 */
	/* 判断是否真的获取到了天气信息，防止获取到了乱码 */
	if(NULL != strstr((const char *)cJSON_Print(cjson_succ_flg), (const char *)"1"))
	{
		Weather_CjsonParse(cJSON_Print(cJSON_GetObjectItem(body, "result")));
		weather_get_succ_flg = 1;
	}
    else
    {
        weather_get_succ_flg = 0;
		weather_update_cnt = 0;
    }
	cJSON_Delete(body);//释放内存  
}

/* 处理获取的JSON代码 */
static void Weather_CjsonParse(char *json_data)
{
	cJSON *body = NULL;    
	cJSON *cjson_weather = NULL;
	cJSON *cjson_temp_L = NULL;
	cJSON *cjson_temp_H = NULL;
	cJSON *cjson_temp_curr = NULL;
	cJSON *cjson_weather_t = NULL;
	cJSON *cjson_humi_curr = NULL;

    body = cJSON_Parse((const char*)json_data);

	cjson_temp_L = cJSON_GetObjectItem(body, "temp_low");
	cjson_temp_H = cJSON_GetObjectItem(body, "temp_high");
	cjson_weather = cJSON_GetObjectItem(body, "weather_curr");
	cjson_weather_t = cJSON_GetObjectItem(body, "weather");
	cjson_temp_curr = cJSON_GetObjectItem(body, "temp_curr");
	cjson_humi_curr = cJSON_GetObjectItem(body, "humidity");

	sscanf(cJSON_Print(cjson_temp_L), "\"%d\"", &weather_info.temp_low);
	sscanf(cJSON_Print(cjson_temp_H), "\"%d\"", &weather_info.temp_high);
	// sscanf(cJSON_Print(cjson_weather), "\"%s\"", weather_info.weather_curr);    //这种方式不能删除后面的引号，用strtok可以
	// sscanf(cJSON_Print(cjson_weather_t), "\"%s\"", weather_info.weather_today);
	sscanf(cJSON_Print(cjson_temp_curr), "\"%d\"", &weather_info.temp_curr);
	sscanf(cJSON_Print(cjson_humi_curr), "\"%d%%\"", &weather_info.humi_curr);
    weather_info.weather_curr = strtok(cJSON_Print(cjson_weather), "\"");
	weather_info.weather_today = strtok(cJSON_Print(cjson_weather_t), "\"");

#if (DEBUG_PRINT == STD_ON)
	printf("%s\r\n", json_data);
	// printf("\n---temp_low:%d\n--temp_high:%d\n--current:%s\n--today:%s\n--current temp:%d\n--current humi:%d\n", weather_info.temp_low, weather_info.temp_high, weather_info.weather_curr,
    //                             weather_info.weather_today, weather_info.temp_curr, weather_info.humi_curr);
#endif
	cJSON_Delete(body);//释放内存  
}

/* 获取天气信息 */
s_WeatherType Weather_GetWeatherInfo(void)
{
    return weather_info;
}

/* 返回天气信息获取成功标志 */
uint8_t Weather_GetSuccessFlg(void)
{
	return weather_get_succ_flg;
}

/* 设置城市代码 */
void Weather_SettingCityCode(uint32_t city_code)
{
	weather_get_succ_flg = 0;    /* To Be update weather information */
	weather_update_cnt = 0;
	city_key = city_code;
	Kv_WriteData(KV_CITY, city_code);
}

/* 获取城市代码 */
uint32_t Weather_GetCityCode(void)
{
	return city_key;
}

/* 置位天气更新标志 */
void Weather_SetUpdateFlg(void)
{
	weather_upt_flg = 1;
}
